home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-23 | 45.9 KB | 1,722 lines |
- Newsgroups: comp.sources.unix
- From: deraadt@cpsc.ucalgary.ca (Theo Deraadt)
- Subject: v25i152: permissions - access control library for YP/NIS environments, Part01/03
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: deraadt@cpsc.ucalgary.ca (Theo Deraadt)
- Posting-Number: Volume 25, Issue 152
- Archive-Name: permissions/part01
-
- [ Permissions is a library for controlling access to machines and resources
- in a network environment. It uses YP for to store and access its database
- of who has permission to do what. Caveat: some people would argue that
- YP and real "security" are orthogonal concepts.
-
- In order to really make use of the library, you will need to have
- and to hack the source of the program (e.g., login.c) that you want to
- have use the library. This could pose a problem to many of you binary-only
- people. [ and the free BSD sources don't have YP in them... --vix ]
-
- Permissions was written by Theo Deraadt <deraadt@cpsc.ucalgary.ca>.
-
- --Nick ]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 3)."
- # Contents: Makefile README examples examples/cpsc.ucalgary.ca in.ftpd
- # in.ftpd/Makefile in.ftpd/logwtmp.c in.ftpd/popen.c in.ftpd/vers.c
- # in.rshd in.rshd/Makefile in.rshd/in.rshd.c login login/Makefile
- # perms perms/Makefile perms/glob_match.c perms/perms.y permtest
- # permtest/Makefile permtest/permtest.c
- # Wrapped by vixie@cognition.pa.dec.com on Tue Mar 10 23:11:20 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(247 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- all:
- X cd perms; $(MAKE)
- X cd permtest; $(MAKE)
- X cd login; $(MAKE)
- X cd in.rshd; $(MAKE)
- X cd in.ftpd; $(MAKE)
- X
- clean:
- X cd perms; $(MAKE) clean
- X cd permtest; $(MAKE) clean
- X cd login; $(MAKE) clean
- X cd in.rshd; $(MAKE) clean
- X cd in.ftpd; $(MAKE) clean
- END_OF_FILE
- if test 247 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2484 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- DESCRIPTION:
- In a basic BSD environemt only three utilities let people onto a machine:
- X login, rshd, and ftpd.
- These three programs are modified to check a YP map called 'permissions'
- which determines whether a person is allowed to login.
- Control over login is given based on four parameters: hostname, ttyname,
- login, and groups.
- X
- The permissions library routines have been tested on suns, iris, and mips
- boxes. The problem is not so much that permissions might be nonportable,
- but rather that source for login is unavailable on the other machines I
- have access to. Writing a workalike login for a system V box is nontrivial.
- permtest, rshd and ftpd have been tested to work though, with minor hacks.
- On a BSD-like box, permissions should be trivial to install.
- X
- Perhaps someone who has written a free system V login could send it to
- me. I'd love to support more architectures/operating systems.
- X
- The permissions library can be used for other purposes too. We also use it
- for printer access. Someone suggested doing device access like dialin/dailout
- and tape drives through it.
- X
- INSTALLATION:
- X1. Building permissions:
- X # make
- X2. Build a permissions map for your network and install it into YP.
- X See your systems manuals for the correct way to install a YP map
- X in your system. Here's what we use in /var/yp/Makefile,
- X
- permissions.time: $(DIR)/permissions
- X @(sed -e "/^#/d" -e s/#.*$$// $(DIR)/permissions $(CHKPIPE)) | \
- X $(MAKEDBM) - $(YPDBDIR)/$(DOM)/permissions;
- X @touch permissions.time;
- X @echo "updated permissions";
- X @if [ ! $(NOPUSH) ]; then $(YPPUSH) -d $(DOM) permissions; fi
- X @if [ ! $(NOPUSH) ]; then echo "pushed permissions"; fi
- X
- X To install the map, on sunos4.1, I would use the following:
- X # touch /etc/permissions
- X # ypmake NOPUSH=1 permissions
- X # foreach i ( `ypcat ypservers` )
- X > rsh $i /usr/etc/yp/ypxfr -h `hostname` permissions
- X > end
- X #
- X
- X5. Test the permissions database with permtest. For example,
- X # permtest -v deraadt ttyh0 fsa
- X 8 groups: staff wheel daemon kmem bin oldstaff telnet cdrom
- X user deraadt permitted on fsa:ttyh0
- X
- X4. Now install the three remaining parts.
- X login/login -> /bin/login
- X in.ftpd/in.ftpd -> /usr/etc/in.ftpd
- X in.rshd/in.rshd -> /usr/etc/in.rshd
- X Be sure to save copies of your old utilities.
- X Remember, on most systems, login is setuid root.
- X
- One request. Please clear all changes to this through me. I would be very
- unhappy to see five different incompatible versions of this in use.
- X
- XEnjoy.
- deraadt@cpsc.ucalgary.ca
- END_OF_FILE
- if test 2484 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test ! -d 'examples' ; then
- echo shar: Creating directory \"'examples'\"
- mkdir 'examples'
- fi
- if test -f 'examples/cpsc.ucalgary.ca' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'examples/cpsc.ucalgary.ca'\"
- else
- echo shar: Extracting \"'examples/cpsc.ucalgary.ca'\" \(4493 characters\)
- sed "s/^X//" >'examples/cpsc.ucalgary.ca' <<'END_OF_FILE'
- X# ----------------------------------------------------------------------
- X# NIS map = permissions
- X# groked by: login, in.rshd, permtest, in.ftpd
- X# rsh and ftp generate tty field values of 'rsh' and 'ftp'
- X#
- X# SYNTAX:
- X# entry : hostname '\t' permlist
- X# permlist : permission `|` permlist
- X# | permission
- X# | null
- X# permission : ttylist ':' authlist
- X# | '$' entry -> #include an entry
- X# ttylist : tty ',' ttylist
- X# | tty -> tty regexp
- X# | null
- X# authlist : auth ',' authlist
- X# | auth
- X# auth : + spec -> add
- X# : - spec -> delete
- X# | null
- X# spec : user -> username to change
- X# | '.' group -> group regexp to change
- X#
- X# NOTES:
- X# Watch how we deny anonomous ftp on every machine with the $admin
- X# macro, then allow it on fsa again. fsa is our admin only machine, and
- X# does not actually run the ftpd included, but rather a logging ftpd.
- X#
- X# Two example users will explain the groups
- X# aycock is in groups: c510/L01, c461/L01, and c401/L01. (His account is
- X# actually in /home/c510/L01/aycock)
- X# deraadt is in groups: staff wheel daemonkmem bin telnet cdrom
- X#
- X# The macros at the top are very important. They groups machines into sets
- X# making their management easier.
- X#
- X# In some places you will see references to tty's. These are our fast modem
- X# racks. We restrict certain groups to using them. Others can go through the
- X# slower campus terminal servers.
- X# ----------------------------------------------------------------------
- X
- X# macros
- admin *:+.utils,+.staff,+.wheel,+operator | ftp:-ftp
- grad_ws $admin | *:+.grads,+.profs,+.research,+.summer,+.gl,+.vlsi,+.srdg,+.c502/L01,+.c599/L01,+.c651/L01
- prof_ws $admin | *:+.profs,+.research,+.srdg,+.offstaff
- vlsi_ws $admin | *:+.vlsi,+graham,+olthof,+jevans,+milligan
- off_ws $admin | *:+.offstaff,+.profs
- ug_ws $admin | $grad_ws | *:+.c[456]*
- X
- X# admin machines
- fsa $admin | ttyb,ttyh?:-.*,+.staff,+.uucp | *:+frangos,+elsie | ftp:+ftp
- aa $admin
- rat $admin | *:+aycock
- sev $admin
- atlas $admin | *:+test,-jamesm
- dudes $admin
- glags $admin
- X
- X# profs machines
- fsc $admin | *:+.grads,+.profs,+.research,+.srdg,+.vlsi,+.offstaff,+.c491/L01,+.banff,+.visitors | ttyj[0-6]:-.*,+.staff,+.profs,+.offstaff,+gl
- interval $prof_ws
- ca $prof_ws
- cb $prof_ws
- cc $prof_ws | *:+.gl
- cd $prof_ws | *:+.grads,+.research,+.srdg,+.vlsi,+joan
- ce $prof_ws
- cf $prof_ws
- cg $prof_ws
- ch $prof_ws
- ic $prof_ws
- golf $prof_ws
- albert $prof_ws
- X
- X# grads machines
- fsd $admin | *:+.grads,+.profs,+.research,+.summer,+.vlsi,+gl,+.srdg,+.c502/L01,+.c599/L01,+.banff,+.arc,+conway | ttyh[0-6]:-.*,+.staff,+.profs,+.grads,+.vlsi,+.offstaff,+.research
- ab $grad_ws | *:+publisher
- da $grad_ws
- db $grad_ws
- dc $grad_ws | *:+joan
- dd $grad_ws
- de $grad_ws
- df $grad_ws
- dg $grad_ws
- dh $grad_ws
- di $grad_ws
- dj $grad_ws
- dk $grad_ws
- ij $grad_ws
- X
- X# vlsi machines
- fsg $vlsi_ws
- ga $vlsi_ws
- gb $vlsi_ws
- gc $vlsi_ws
- gd $vlsi_ws
- ge $vlsi_ws
- gf $vlsi_ws
- gg $vlsi_ws
- gh $vlsi_ws
- X
- X# office staff machines
- ia $off_ws
- ih $off_ws
- X
- X# undergraduate workstations
- ea $ug_ws
- eb $ug_ws
- ec $ug_ws
- ed $ug_ws
- ee $ug_ws
- ef $ug_ws
- eg $ug_ws
- eh $ug_ws
- ei $ug_ws
- ej $ug_ws
- ha $ug_ws
- hb $ug_ws
- hc $ug_ws
- hd $ug_ws
- he $ug_ws
- hf $ug_ws
- hg $ug_ws
- hh $ug_ws
- hi $ug_ws
- ib $ug_ws
- id $ug_ws
- ie $ug_ws
- if $ug_ws
- X
- X# graphicsland fileserver
- gfx $admin | *:+.gl,+thorne
- X
- X# myths. these machines do not run the right login yet.
- bfly $grad_ws
- irisa $admin | *:+.gl,+.c55[13]*
- irisb $admin | *:+.gl,+.c55[13]*
- irisc $admin | *:+.gl
- irisd $admin | *:+.gl
- irise $admin | *:+.gl
- irisf $admin | *:+.gl,+.c55[13]*
- X
- X# remaining machines. Anyone may use an undergrad machine.
- X# be careful - the $admin is at the end to turn off anon ftp
- X* *:+.*,-.uucp | $admin
- X
- X# PRINTERS
- X# Our printer permissions are done through permissions as well. Sorry,
- X# this distribution of permissions does not include our lpr hacks.
- X# I left this in here simply as an example.
- X
- lp1 *:+.*,-.nlp
- lp2 *:+.*,-.nlp
- X
- cs1 $admin | *:+.grads,+.research,+.profs,+.offstaff,+.srdg,+.submit | *:+.cs1,-.ncs1
- cs2 $admin | *:+.grads,+.research,+.profs,+.offstaff,+.srdg,+.vlsi | *:+.cs2,-.ncs2
- X
- alw1 $admin | *:+.profs,+.offstaff,+.grads | *:+.alw1,-.nalw1
- alw2 $admin | *:+.profs,+.offstaff,+.vlsi | *:+.alw2,-.nalw2
- alw3 $admin | *:+.grads,+.research,+.profs,+.srdg,+.vlsi | *:+.alw3,-.nalw3
- alw4 $admin | *:+.grads,+.research,+.profs,+.offstaff,+.srdg,+.vlsi | *:+.alw4,-.nalw4
- X
- bp $admin | *:+.bp,-.nbp
- ip $admin | *:+.grads,+.research,+.profs,+.srdg,+.c481* | *:+.ip,-.nip
- END_OF_FILE
- if test 4493 -ne `wc -c <'examples/cpsc.ucalgary.ca'`; then
- echo shar: \"'examples/cpsc.ucalgary.ca'\" unpacked with wrong size!
- fi
- # end of 'examples/cpsc.ucalgary.ca'
- fi
- if test ! -d 'in.ftpd' ; then
- echo shar: Creating directory \"'in.ftpd'\"
- mkdir 'in.ftpd'
- fi
- if test -f 'in.ftpd/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.ftpd/Makefile'\"
- else
- echo shar: Extracting \"'in.ftpd/Makefile'\" \(203 characters\)
- sed "s/^X//" >'in.ftpd/Makefile' <<'END_OF_FILE'
- OBJ = ftpd.o ftpcmd.o glob.o popen.o logwtmp.o vers.o\
- X ../perms/perms.o ../perms/glob_match.o
- CFLAGS = -g -DPERMS
- X
- in.ftpd: $(OBJ)
- X $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ)
- X
- clean:
- X $(RM) *.o *~ in.ftpd
- END_OF_FILE
- if test 203 -ne `wc -c <'in.ftpd/Makefile'`; then
- echo shar: \"'in.ftpd/Makefile'\" unpacked with wrong size!
- fi
- # end of 'in.ftpd/Makefile'
- fi
- if test -f 'in.ftpd/logwtmp.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.ftpd/logwtmp.c'\"
- else
- echo shar: Extracting \"'in.ftpd/logwtmp.c'\" \(1604 characters\)
- sed "s/^X//" >'in.ftpd/logwtmp.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1988 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X */
- X
- X#ifndef lint
- static char sccsid[] = "@(#)logwtmp.c 1.1 90/03/23 SMI"; /* from UCB 5.3 12/7/88 */
- X#endif /* not lint */
- X
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <sys/time.h>
- X#include <sys/stat.h>
- X#include <utmp.h>
- X
- X#define WTMPFILE "/var/adm/wtmp"
- X
- static int fd = -1;
- X
- X/*
- X * Modified version of logwtmp that holds wtmp file open
- X * after first call, for use with ftp (which may chroot
- X * after login, but before logout).
- X */
- logwtmp(line, name, host)
- X char *line, *name, *host;
- X{
- X struct utmp ut;
- X struct stat buf;
- X time_t time();
- X char *strncpy();
- X
- X if (fd < 0 && (fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
- X return;
- X if (fstat(fd, &buf) == 0) {
- X (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
- X (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
- X (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
- X (void)time(&ut.ut_time);
- X if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
- X sizeof(struct utmp))
- X (void)ftruncate(fd, buf.st_size);
- X }
- X}
- END_OF_FILE
- if test 1604 -ne `wc -c <'in.ftpd/logwtmp.c'`; then
- echo shar: \"'in.ftpd/logwtmp.c'\" unpacked with wrong size!
- fi
- # end of 'in.ftpd/logwtmp.c'
- fi
- if test -f 'in.ftpd/popen.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.ftpd/popen.c'\"
- else
- echo shar: Extracting \"'in.ftpd/popen.c'\" \(3504 characters\)
- sed "s/^X//" >'in.ftpd/popen.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1988 The Regents of the University of California.
- X * All rights reserved.
- X *
- X * This code is derived from software written by Ken Arnold and
- X * published in UNIX Review, Vol. 6, No. 8.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X */
- X
- X#ifndef lint
- static char sccsid[] = "@(#)popen.c 1.1 90/03/23 SMI"; /* from UCB 5.4 12/7/88 */
- X#endif /* not lint */
- X
- X#include <sys/types.h>
- X#include <sys/signal.h>
- X#include <sys/wait.h>
- X#include <stdio.h>
- X
- X/*
- X * Special version of popen which avoids call to shell. This insures noone
- X * may create a pipe to a hidden program as a side effect of a list or dir
- X * command.
- X */
- static int *pids;
- static int fds;
- X
- XFILE *
- ftpd_popen(program, type)
- X char *program, *type;
- X{
- X register char *cp;
- X FILE *iop;
- X int argc, gargc, pdes[2], pid;
- X char **pop, *argv[100], *gargv[1000], *vv[2];
- X extern char **glob(), **copyblk(), *strtok(), *malloc();
- X
- X if (*type != 'r' && *type != 'w' || type[1])
- X return(NULL);
- X
- X if (!pids) {
- X if ((fds = getdtablesize()) <= 0)
- X return(NULL);
- X if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
- X return(NULL);
- X bzero((char *)pids, fds * sizeof(int));
- X }
- X if (pipe(pdes) < 0)
- X return(NULL);
- X
- X /* break up string into pieces */
- X for (argc = 0, cp = program;; cp = NULL)
- X if (!(argv[argc++] = strtok(cp, " \t\n")))
- X break;
- X
- X /* glob each piece */
- X gargv[0] = argv[0];
- X for (gargc = argc = 1; argv[argc]; argc++) {
- X if (!(pop = glob(argv[argc]))) { /* globbing failed */
- X vv[0] = argv[argc];
- X vv[1] = NULL;
- X pop = copyblk(vv);
- X }
- X argv[argc] = (char *)pop; /* save to free later */
- X while (*pop && gargc < 1000)
- X gargv[gargc++] = *pop++;
- X }
- X gargv[gargc] = NULL;
- X
- X iop = NULL;
- X switch(pid = vfork()) {
- X case -1: /* error */
- X (void)close(pdes[0]);
- X (void)close(pdes[1]);
- X goto free;
- X /* NOTREACHED */
- X case 0: /* child */
- X if (*type == 'r') {
- X if (pdes[1] != 1) {
- X /*
- X * Need to grab stderr too for new ls
- X */
- X dup2(pdes[1], 2);
- X dup2(pdes[1], 1);
- X (void)close(pdes[1]);
- X }
- X (void)close(pdes[0]);
- X } else {
- X if (pdes[0] != 0) {
- X dup2(pdes[0], 0);
- X (void)close(pdes[0]);
- X }
- X (void)close(pdes[1]);
- X }
- X execv(gargv[0], gargv);
- X _exit(1);
- X }
- X /* parent; assume fdopen can't fail... */
- X if (*type == 'r') {
- X iop = fdopen(pdes[0], type);
- X (void)close(pdes[1]);
- X } else {
- X iop = fdopen(pdes[1], type);
- X (void)close(pdes[0]);
- X }
- X pids[fileno(iop)] = pid;
- X
- free: for (argc = 1; argv[argc] != NULL; argc++)
- X blkfree((char **)argv[argc]);
- X return(iop);
- X}
- X
- ftpd_pclose(iop)
- X FILE *iop;
- X{
- X register int fdes;
- X int omask;
- X union wait stat_loc;
- X int pid;
- X
- X /*
- X * pclose returns -1 if stream is not associated with a
- X * `popened' command, or, if already `pclosed'.
- X */
- X if (pids == 0 || pids[fdes = fileno(iop)] == 0)
- X return(-1);
- X (void)fclose(iop);
- X omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
- X while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1);
- X (void)sigsetmask(omask);
- X pids[fdes] = 0;
- X return(pid == -1 ? -1 : stat_loc.w_status);
- X}
- END_OF_FILE
- if test 3504 -ne `wc -c <'in.ftpd/popen.c'`; then
- echo shar: \"'in.ftpd/popen.c'\" unpacked with wrong size!
- fi
- # end of 'in.ftpd/popen.c'
- fi
- if test -f 'in.ftpd/vers.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.ftpd/vers.c'\"
- else
- echo shar: Extracting \"'in.ftpd/vers.c'\" \(64 characters\)
- sed "s/^X//" >'in.ftpd/vers.c' <<'END_OF_FILE'
- X/* @(#)vers.c 1.1 90/03/23 SMI */
- char version[] = "SunOS 4.1";
- END_OF_FILE
- if test 64 -ne `wc -c <'in.ftpd/vers.c'`; then
- echo shar: \"'in.ftpd/vers.c'\" unpacked with wrong size!
- fi
- # end of 'in.ftpd/vers.c'
- fi
- if test ! -d 'in.rshd' ; then
- echo shar: Creating directory \"'in.rshd'\"
- mkdir 'in.rshd'
- fi
- if test -f 'in.rshd/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.rshd/Makefile'\"
- else
- echo shar: Extracting \"'in.rshd/Makefile'\" \(160 characters\)
- sed "s/^X//" >'in.rshd/Makefile' <<'END_OF_FILE'
- OBJ = in.rshd.o ../perms/perms.o ../perms/glob_match.o
- CFLAGS = -g -DPERMS
- X
- in.rshd: $(OBJ)
- X $(CC) $(LDFLAGS) $(OBJ) -o in.rshd
- X
- clean:
- X $(RM) *~ *.o in.rshd
- END_OF_FILE
- if test 160 -ne `wc -c <'in.rshd/Makefile'`; then
- echo shar: \"'in.rshd/Makefile'\" unpacked with wrong size!
- fi
- # end of 'in.rshd/Makefile'
- fi
- if test -f 'in.rshd/in.rshd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'in.rshd/in.rshd.c'\"
- else
- echo shar: Extracting \"'in.rshd/in.rshd.c'\" \(6522 characters\)
- sed "s/^X//" >'in.rshd/in.rshd.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1983 Regents of the University of California.
- X * All rights reserved. The Berkeley software License Agreement
- X * specifies the terms and conditions for redistribution.
- X */
- X
- X#ifndef lint
- char copyright[] =
- X"@(#) Copyright (c) 1983 Regents of the University of California.\n\
- X All rights reserved.\n";
- X#endif not lint
- X
- X#ifndef lint
- static char sccsid[] = "@(#)rshd.c 5.7 (Berkeley) 5/9/86";
- X#endif not lint
- X
- X/*
- X * remote shell server:
- X * remuser\0
- X * locuser\0
- X * command\0
- X * data
- X */
- X#include <sys/ioctl.h>
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X
- X#include <netinet/in.h>
- X
- X#include <arpa/inet.h>
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <pwd.h>
- X#include <signal.h>
- X#include <netdb.h>
- X#include <syslog.h>
- X
- X
- X#ifdef PERMS
- X#include <grp.h>
- char *strdup(), *grpnames[NGROUPS+1];
- int ngrps, lp;
- struct group *grp;
- extern int permcheck();
- X#endif
- X
- int errno;
- char *index(), *rindex(), *strncat();
- X/*VARARGS1*/
- int error();
- X
- X/*ARGSUSED*/
- main(argc, argv)
- X int argc;
- X char **argv;
- X{
- X struct linger linger;
- X int on = 1, fromlen;
- X struct sockaddr_in from;
- X
- X openlog("rsh", LOG_PID | LOG_ODELAY, LOG_DAEMON);
- X fromlen = sizeof (from);
- X if (getpeername(0, &from, &fromlen) < 0) {
- X fprintf(stderr, "%s: ", argv[0]);
- X perror("getpeername");
- X _exit(1);
- X }
- X if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
- X sizeof (on)) < 0)
- X syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
- X linger.l_onoff = 1;
- X linger.l_linger = 60; /* XXX */
- X if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger,
- X sizeof (linger)) < 0)
- X syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m");
- X doit(dup(0), &from);
- X}
- X
- char username[20] = "USER=";
- char homedir[64] = "HOME=";
- char shell[64] = "SHELL=";
- char *envinit[] =
- X {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", username, 0};
- char **environ;
- X
- doit(f, fromp)
- X int f;
- X struct sockaddr_in *fromp;
- X{
- X char cmdbuf[NCARGS+1], *cp;
- X char locuser[16], remuser[16];
- X struct passwd *pwd;
- X int s;
- X struct hostent *hp;
- X char *hostname;
- X short port;
- X int pv[2], pid, ready, readfrom, cc;
- X char buf[BUFSIZ], sig;
- X int one = 1;
- X
- X (void) signal(SIGINT, SIG_DFL);
- X (void) signal(SIGQUIT, SIG_DFL);
- X (void) signal(SIGTERM, SIG_DFL);
- X#ifdef DEBUG
- X { int t = open("/dev/tty", 2);
- X if (t >= 0) {
- X ioctl(t, TIOCNOTTY, (char *)0);
- X (void) close(t);
- X }
- X }
- X#endif
- X fromp->sin_port = ntohs((u_short)fromp->sin_port);
- X if (fromp->sin_family != AF_INET ||
- X fromp->sin_port >= IPPORT_RESERVED) {
- X syslog(LOG_ERR, "malformed from address\n");
- X exit(1);
- X }
- X (void) alarm(60);
- X port = 0;
- X for (;;) {
- X char c;
- X if (read(f, &c, 1) != 1) {
- X syslog(LOG_ERR, "read: %m");
- X shutdown(f, 1+1);
- X exit(1);
- X }
- X if (c == 0)
- X break;
- X port = port * 10 + c - '0';
- X }
- X (void) alarm(0);
- X if (port != 0) {
- X int lport = IPPORT_RESERVED - 1;
- X s = rresvport(&lport);
- X if (s < 0) {
- X syslog(LOG_ERR, "can't get stderr port: %m");
- X exit(1);
- X }
- X if (port >= IPPORT_RESERVED) {
- X syslog(LOG_ERR, "2nd port not reserved\n");
- X exit(1);
- X }
- X fromp->sin_port = htons((u_short)port);
- X if (connect(s, fromp, sizeof (*fromp)) < 0) {
- X syslog(LOG_INFO, "connect second port: %m");
- X exit(1);
- X }
- X }
- X dup2(f, 0);
- X dup2(f, 1);
- X dup2(f, 2);
- X hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof (struct in_addr),
- X fromp->sin_family);
- X if (hp)
- X hostname = hp->h_name;
- X else
- X hostname = inet_ntoa(fromp->sin_addr);
- X getstr(remuser, sizeof(remuser), "remuser");
- X getstr(locuser, sizeof(locuser), "locuser");
- X getstr(cmdbuf, sizeof(cmdbuf), "command");
- X setpwent();
- X pwd = getpwnam(locuser);
- X if (pwd == NULL) {
- X error("Login incorrect.\n");
- X exit(1);
- X }
- X endpwent();
- X if (chdir(pwd->pw_dir) < 0) {
- X (void) chdir("/");
- X#ifdef notdef
- X error("No remote directory.\n");
- X exit(1);
- X#endif
- X }
- X if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
- X ruserok(hostname, pwd->pw_uid == 0, remuser, locuser) < 0) {
- X error("Permission denied.\n");
- X exit(1);
- X }
- X
- X#ifdef PERMS
- X /* build groups so we can look them up in 'permissions'
- X * this check is not run for uid 0
- X */
- X if(pwd->pw_uid != 0) {
- X setgrent();
- X ngrps = 0;
- X grp=getgrgid(pwd->pw_gid);
- X grpnames[ngrps++] = strdup(grp->gr_name);
- X while( grp=getgrent() ) {
- X if(pwd->pw_gid == grp->gr_gid)
- X continue;
- X while(*grp->gr_mem) {
- X if( !strcmp(locuser, *grp->gr_mem)) {
- X grpnames[ngrps++] = strdup(grp->gr_name);
- X }
- X grp->gr_mem++;
- X }
- X }
- X endgrent();
- X grpnames[ngrps] = NULL;
- X
- X lp = permcheck(locuser, "rsh", grpnames, NULL);
- X if(!lp) {
- X syslog(LOG_CRIT,
- X "rsh:%s not permitted", locuser);
- X error("Permission denied.\n");
- X exit(1);
- X }
- X }
- X#endif
- X
- X (void) write(2, "\0", 1);
- X if (port) {
- X if (pipe(pv) < 0) {
- X error("Can't make pipe.\n");
- X exit(1);
- X }
- X pid = fork();
- X if (pid == -1) {
- X error("Try again.\n");
- X exit(1);
- X }
- X if (pid) {
- X (void) close(0); (void) close(1); (void) close(2);
- X (void) close(f); (void) close(pv[1]);
- X readfrom = (1<<s) | (1<<pv[0]);
- X ioctl(pv[0], FIONBIO, (char *)&one);
- X /* should set s nbio! */
- X do {
- X ready = readfrom;
- X if (select(16, &ready, (fd_set *)0,
- X (fd_set *)0, (struct timeval *)0) < 0)
- X break;
- X if (ready & (1<<s)) {
- X if (read(s, &sig, 1) <= 0)
- X readfrom &= ~(1<<s);
- X else
- X killpg(pid, sig);
- X }
- X if (ready & (1<<pv[0])) {
- X errno = 0;
- X cc = read(pv[0], buf, sizeof (buf));
- X if (cc <= 0) {
- X shutdown(s, 1+1);
- X readfrom &= ~(1<<pv[0]);
- X } else
- X (void) write(s, buf, cc);
- X }
- X } while (readfrom);
- X exit(0);
- X }
- X setpgrp(0, getpid());
- X (void) close(s); (void) close(pv[0]);
- X dup2(pv[1], 2);
- X }
- X if (*pwd->pw_shell == '\0')
- X pwd->pw_shell = "/bin/sh";
- X (void) close(f);
- X (void) setgid((gid_t)pwd->pw_gid);
- X initgroups(pwd->pw_name, pwd->pw_gid);
- X (void) setuid((uid_t)pwd->pw_uid);
- X environ = envinit;
- X strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
- X strncat(shell, pwd->pw_shell, sizeof(shell)-7);
- X strncat(username, pwd->pw_name, sizeof(username)-6);
- X cp = rindex(pwd->pw_shell, '/');
- X if (cp)
- X cp++;
- X else
- X cp = pwd->pw_shell;
- X execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
- X perror(pwd->pw_shell);
- X exit(1);
- X}
- X
- X/*VARARGS1*/
- error(fmt, a1, a2, a3)
- X char *fmt;
- X int a1, a2, a3;
- X{
- X char buf[BUFSIZ];
- X
- X buf[0] = 1;
- X (void) sprintf(buf+1, fmt, a1, a2, a3);
- X (void) write(2, buf, strlen(buf));
- X}
- X
- getstr(buf, cnt, err)
- X char *buf;
- X int cnt;
- X char *err;
- X{
- X char c;
- X
- X do {
- X if (read(0, &c, 1) != 1)
- X exit(1);
- X *buf++ = c;
- X if (--cnt == 0) {
- X error("%s too long\n", err);
- X exit(1);
- X }
- X } while (c != 0);
- X}
- END_OF_FILE
- if test 6522 -ne `wc -c <'in.rshd/in.rshd.c'`; then
- echo shar: \"'in.rshd/in.rshd.c'\" unpacked with wrong size!
- fi
- # end of 'in.rshd/in.rshd.c'
- fi
- if test ! -d 'login' ; then
- echo shar: Creating directory \"'login'\"
- mkdir 'login'
- fi
- if test -f 'login/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'login/Makefile'\"
- else
- echo shar: Extracting \"'login/Makefile'\" \(164 characters\)
- sed "s/^X//" >'login/Makefile' <<'END_OF_FILE'
- OBJ = login.o ../perms/perms.o ../perms/glob_match.o
- CFLAGS = -g -DPERMS -DMAILPING
- X
- login: $(OBJ)
- X $(CC) $(LDFLAGS) $(OBJ) -o login
- X
- clean:
- X $(RM) *~ *.o login
- END_OF_FILE
- if test 164 -ne `wc -c <'login/Makefile'`; then
- echo shar: \"'login/Makefile'\" unpacked with wrong size!
- fi
- # end of 'login/Makefile'
- fi
- if test ! -d 'perms' ; then
- echo shar: Creating directory \"'perms'\"
- mkdir 'perms'
- fi
- if test -f 'perms/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'perms/Makefile'\"
- else
- echo shar: Extracting \"'perms/Makefile'\" \(293 characters\)
- sed "s/^X//" >'perms/Makefile' <<'END_OF_FILE'
- YACCFLAGS = -d
- OBJ = perms.o glob_match.o
- CFLAGS = -g -DPERMS
- X
- all: glob_match.o perms.o
- X
- perms.o: perms.y
- X yacc $(YACCFLAGS) perms.y
- X sed -e "s/yy/xx/g" -e "s/YY/XX/g" y.tab.c > x.tab.c
- X $(CC) $(CFLAGS) -c x.tab.c -o perms.o
- X $(RM) y.tab.c x.tab.c
- X
- clean:
- X $(RM) *~ *.o y.tab.h y.tab.c
- END_OF_FILE
- if test 293 -ne `wc -c <'perms/Makefile'`; then
- echo shar: \"'perms/Makefile'\" unpacked with wrong size!
- fi
- # end of 'perms/Makefile'
- fi
- if test -f 'perms/glob_match.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'perms/glob_match.c'\"
- else
- echo shar: Extracting \"'perms/glob_match.c'\" \(7660 characters\)
- sed "s/^X//" >'perms/glob_match.c' <<'END_OF_FILE'
- X/* File-name wildcard pattern matching for GNU.
- X Copyright (C) 1985, 1988 Free Software Foundation, Inc.
- X
- X NO WARRANTY
- X
- X BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
- NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
- WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
- RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
- WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
- AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
- DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
- CORRECTION.
- X
- X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
- STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
- WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
- LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
- OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
- USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
- DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
- A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
- PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- X
- X GENERAL PUBLIC LICENSE TO COPY
- X
- X 1. You may copy and distribute verbatim copies of this source file
- as you receive it, in any medium, provided that you conspicuously and
- appropriately publish on each copy a valid copyright notice "Copyright
- X(C) 1988 Free Software Foundation, Inc."; and include following the
- copyright notice a verbatim copy of the above disclaimer of warranty
- and of this License.
- X
- X 2. You may modify your copy or copies of this source file or
- any portion of it, and copy and distribute such modifications under
- the terms of Paragraph 1 above, provided that you also do the following:
- X
- X a) cause the modified files to carry prominent notices stating
- X that you changed the files and the date of any change; and
- X
- X b) cause the whole of any work that you distribute or publish,
- X that in whole or in part contains or is a derivative of this
- X program or any part thereof, to be licensed at no charge to all
- X third parties on terms identical to those contained in this
- X License Agreement (except that you may choose to grant more extensive
- X warranty protection to some or all third parties, at your option).
- X
- X c) You may charge a distribution fee for the physical act of
- X transferring a copy, and you may at your option offer warranty
- X protection in exchange for a fee.
- X
- Mere aggregation of another unrelated program with this program (or its
- derivative) on a volume of a storage or distribution medium does not bring
- the other program under the scope of these terms.
- X
- X 3. You may copy and distribute this program (or a portion or derivative
- of it, under Paragraph 2) in object code or executable form under the terms
- of Paragraphs 1 and 2 above provided that you also do one of the following:
- X
- X a) accompany it with the complete corresponding machine-readable
- X source code, which must be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X b) accompany it with a written offer, valid for at least three
- X years, to give any third party free (except for a nominal
- X shipping charge) a complete machine-readable copy of the
- X corresponding source code, to be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X c) accompany it with the information you received as to where the
- X corresponding source code may be obtained. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form alone.)
- X
- XFor an executable file, complete source code means all the source code for
- all modules it contains; but, as a special exception, it need not include
- source code for modules which are standard libraries that accompany the
- operating system on which the executable file runs.
- X
- X 4. You may not copy, sublicense, distribute or transfer this program
- except as expressly provided under this License Agreement. Any attempt
- otherwise to copy, sublicense, distribute or transfer this program is void and
- your rights to use the program under this License agreement shall be
- automatically terminated. However, parties who have received computer
- software programs from you with this License Agreement will not have
- their licenses terminated so long as such parties remain in full compliance.
- X
- X
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding! */
- X
- X/* Match the pattern PATTERN against the string TEXT;
- X return 1 if it matches, 0 otherwise.
- X
- X A match means the entire string TEXT is used up in matching.
- X
- X In the pattern string, `*' matches any sequence of characters,
- X `?' matches any character, [SET] matches any character in the specified set,
- X [^SET] matches any character not in the specified set.
- X
- X A set is composed of characters or ranges; a range looks like
- X character hyphen character (as in 0-9 or A-Z).
- X [0-9a-zA-Z_] is the set of characters allowed in C identifiers.
- X Any other character in the pattern must be matched exactly.
- X
- X To suppress the special syntactic significance of any of `[]*?^-\',
- X and match the character exactly, precede it with a `\'.
- X
- X If DOT_SPECIAL is nonzero,
- X `*' and `?' do not match `.' at the beginning of TEXT. */
- X
- int
- glob_match (pattern, text, dot_special)
- X char *pattern, *text;
- X int dot_special;
- X{
- X register char *p = pattern, *t = text;
- X register char c;
- X
- X while ((c = *p++))
- X {
- X switch (c)
- X {
- X case '?':
- X if (*t == 0 || (dot_special && t == text && *t == '.')) return 0;
- X else ++t;
- X break;
- X
- X case '\\':
- X if (*p++ != *t++) return 0;
- X break;
- X
- X case '*':
- X if (dot_special && t == text && *t == '.')
- X return 0;
- X return star_glob_match (p, t);
- X
- X case '[':
- X {
- X register char c1 = *t++;
- X register int invert = (*p == '^');
- X
- X if (invert) p++;
- X
- X c = *p++;
- X while (1)
- X {
- X register char cstart = c, cend = c;
- X
- X if (c == '\\')
- X {
- X cstart = *p++; cend = cstart;
- X }
- X c = *p++;
- X if (c == '-')
- X { cend = *p++; if (cend == '\\') cend = *p++; c = *p++; }
- X if (c1 >= cstart && c1 <= cend) goto match;
- X if (c == ']')
- X break;
- X }
- X if (!invert) return 0;
- X break;
- X
- X match:
- X /* Skip the rest of the [...] construct that already matched. */
- X while (c != ']')
- X {
- X c = *p++;
- X if (c == '\\') p++;
- X }
- X if (invert) return 0;
- X break;
- X }
- X
- X default:
- X if (c != *t++) return 0;
- X }
- X }
- X
- X if (*t) return 0;
- X return 1;
- X}
- X
- X/* Like glob_match, but match PATTERN against any final segment of TEXT. */
- X
- static int
- star_glob_match (pattern, text)
- X char *pattern, *text;
- X{
- X register char *p = pattern, *t = text;
- X register char c, c1;
- X
- X while ((c = *p++) == '?' || c == '*')
- X {
- X if (c == '?' && *t++ == 0)
- X return 0;
- X }
- X
- X if (c == 0)
- X return 1;
- X
- X if (c == '\\') c1 = *p;
- X else c1 = c;
- X
- X for (;;)
- X {
- X if ((c == '[' || *t == c1)
- X && glob_match (p - 1, t, 0))
- X return 1;
- X if (*t++ == 0) return 0;
- X }
- X}
- END_OF_FILE
- if test 7660 -ne `wc -c <'perms/glob_match.c'`; then
- echo shar: \"'perms/glob_match.c'\" unpacked with wrong size!
- fi
- # end of 'perms/glob_match.c'
- fi
- if test -f 'perms/perms.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'perms/perms.y'\"
- else
- echo shar: Extracting \"'perms/perms.y'\" \(7791 characters\)
- sed "s/^X//" >'perms/perms.y' <<'END_OF_FILE'
- X/* Copyright (c) 1990 Theo de Raadt deraadt@cpsc.ucalgary.ca
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by Theo de Raadt.
- X */
- X%{
- X#ifndef lint
- char Copyright[] =
- X"@(#) Copyright (c) 1990 Theo de Raadt.\nAll rights reserved.\n";
- X#endif not lint
- X
- X#ifndef lint
- static char Sccsid[] = "@(#)perms.y 1.0 90/11/01 TDR";
- X#endif not lint
- X
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/file.h>
- X#include <netinet/in.h>
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X#include <pwd.h>
- X#include <grp.h>
- X#include <rpc/types.h>
- X#include <rpc/rpc.h>
- X#include <rpcsvc/ypclnt.h>
- X#include <rpcsvc/yp_prot.h>
- X#include <syslog.h>
- X#include "y.tab.h"
- X
- X#undef DEBUG
- X
- X/* define SECURE if you want logins disallowed if errors show up
- X * during a map lookup. If this is not set, YP failures, incorrect
- X * maps, automount failure, etc.,will let anymore login until the
- X * problem is fixed. In general, you never want to define this!
- X */
- X#undef SECURE
- X
- X#define SEARCHMAP "permissions"
- X
- X#define LX_SP 0x00
- X#define LX_EOF 0x01
- X#define LX_C 0x02
- X#define LX_X 0x04
- X#define LX_SC 0x08
- X#define LX_S1 0x10
- static char lookup[] = {
- X 0x01, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 00-07 */
- X 0x04, 0x00, 0x01, 0x04, 0x04, 0x01, 0x04, 0x04, /* 08-0f */
- X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 10-17 */
- X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 18-1f */
- X 0x00, 0x02, 0x04, 0x04, 0x02, 0x04, 0x02, 0x04, /* 20-27 */
- X 0x18, 0x18, 0x18, 0x02, 0x02, 0x0a, 0x18, 0x18, /* 28-2f */
- X 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 30-37 */
- X 0x18, 0x18, 0x02, 0x04, 0x04, 0x04, 0x04, 0x18, /* 38-3f */
- X 0x02, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 40-47 */
- X 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 48-4f */
- X 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 50-57 */
- X 0x18, 0x18, 0x18, 0x18, 0x04, 0x18, 0x18, 0x18, /* 58-5f */
- X 0x04, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 60-67 */
- X 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 68-6f */
- X 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 70-77 */
- X 0x18, 0x18, 0x18, 0x04, 0x02, 0x04, 0x04, 0x04, /* 78-7f */
- X};
- X
- X#define YYSTYPE caddr_t
- extern YYSTYPE yylval;
- X
- static char *grplst[NGROUPS], **grplist;
- char domain[MAXHOSTNAMELEN], key[MAXHOSTNAMELEN];
- static char *usern, *ttyn, *line;
- static int ttymatch, grpusrmatch;
- X
- static int allow, err_allow;
- static char *stack[20];
- static int stackp;
- X
- static
- yyerror() {
- X syslog(LOG_CRIT,
- X "permissions: [key %s] parsing error\n", key);
- X err_allow = 1;
- X}
- X
- X/*
- X * noisy, specifies to be noisy on failure or not
- X */
- static char *
- getypent(s, noisy)
- char *s;
- X{
- X char *entry;
- X int entrylen, err;
- X
- X err = yp_match(domain, SEARCHMAP, s, strlen(s), &entry, &entrylen);
- X if(err) {
- X if(noisy) syslog(LOG_CRIT,
- X "yperr: [key %s] %s\n", s, yperr_string(err));
- X return NULL;
- X }
- X return entry;
- X}
- X
- X/* usr: user name. Absolutely has to be the login name.
- X * tty: tty name. if NULL, any tty will match.
- X * grps: NULL terminated array of group names. If grps==NULL, perms
- X * will fetch the groups using getpwent() and getgrent(). These
- X * have static data -- beware.
- X * lkey: base lookup key. If NULL, hostname will be used.
- X *
- X * return values need cleaning up.
- X * 1 - allowed
- X * 0 - not allowed
- X * -1 - error
- X */
- int
- permcheck(usr, tty, grps, lkey)
- char *usr, *tty, **grps, *lkey;
- X{
- X struct passwd *pwd;
- X struct group *grp;
- X int ngrps = 0;
- X
- X if(!usr)
- X return -1;
- X if(!grps) {
- X grps = grplst;
- X#ifdef DEBUG
- X printf("user: %s\n", usr);
- X#endif
- X setpwent();
- X if( !(pwd=getpwnam(usr)))
- X return -1;
- X#ifdef DEBUG
- X printf("user: (%s)\n", pwd->pw_name);
- X#endif
- X
- X setgrent();
- X if( !(grp=getgrgid(pwd->pw_gid)) )
- X return -1;
- X *grps++ = strdup(grp->gr_name);
- X#ifdef DEBUG
- X printf("group: %s\n", grp->gr_name);
- X#endif
- X ngrps++;
- X while( grp=getgrent() ) {
- X if(pwd->pw_gid == grp->gr_gid)
- X continue;
- X while(*grp->gr_mem) {
- X if(!strcmp(*grp->gr_mem, usr)) {
- X if(++ngrps>NGROUPS)
- X break;
- X *grps++ = strdup(grp->gr_name);
- X#ifdef DEBUG
- X printf("group: %s\n", grp->gr_name);
- X#endif
- X }
- X grp->gr_mem++;
- X }
- X }
- X endgrent();
- X endpwent();
- X *grps = NULL;
- X grps = grplst;
- X }
- X if(lkey)
- X strcpy(key, lkey);
- X else
- X gethostname(key, sizeof key);
- X
- X getdomainname(domain, sizeof domain);
- X if( !(line=getypent(key, 0)) ) {
- X line = getypent("*", 1);
- X }
- X allow = 0;
- X err_allow = !line;
- X
- X if(line) {
- X usern = usr;
- X ttyn = tty;
- X grplist = grps;
- X ttymatch = grpusrmatch = -1;
- X yyparse();
- X }
- X
- X#ifdef SECURE
- X return allow;
- X#else
- X return allow | err_allow;
- X#endif
- X}
- X
- static
- newmap(s)
- char *s;
- X{
- X#ifdef DEBUG
- X printf("include %s, pushing %s", s, line);
- X#endif
- X stack[stackp++] = line;
- X if(stackp==sizeof(stack)/sizeof(char *)) {
- X syslog(LOG_CRIT,
- X "permissions: stack overflow on [key %s]\n", s);
- X line = stack[--stackp];
- X err_allow = 1;
- X return;
- X }
- X line = getypent(s,1);
- X if(!line) {
- X syslog(LOG_CRIT,
- X "permissions: [key %s] not found\n", s);
- X line = stack[--stackp];
- X err_allow = 1;
- X return;
- X }
- X#ifdef DEBUG
- X printf("result %s", line);
- X#endif
- X}
- X
- static
- yylex()
- X{
- X static pos = 0;
- X static char savebuf[1024], *p;
- X char c;
- X
- restartlex:
- X p = savebuf;
- X while(1)
- X switch( lookup[(c= *line++)] ) {
- X case LX_SP:
- X break;
- X case LX_EOF:
- X if(!stackp)
- X return -1;
- X line = stack[--stackp];
- X#ifdef DEBUG
- X printf("popping %s", line);
- X#endif
- X goto restartlex;
- X case LX_C:
- X case LX_C|LX_SC:
- X#ifdef DEBUG
- X printf("lex: char '%c'\n", c);
- X#endif
- X return c;
- X case LX_X:
- X syslog(LOG_CRIT,
- X "permissions: [key %s] illegal char 0%3o\n",
- X key, c);
- X err_allow = 1;
- X return -1;
- X case LX_S1:
- X case LX_S1|LX_SC:
- X do {
- X *p++ = c;
- X c = *line++;
- X } while( lookup[c]&LX_SC );
- X *p = '\0';
- X line--;
- X yylval = savebuf;
- X#ifdef DEBUG
- X printf("lex: symbol %s\n", savebuf);
- X#endif
- X return SYMBOL;
- X }
- X}
- X
- static void
- grpcheck(s, add)
- char *s;
- X{
- X FILE *fin;
- X char **grp, *p, buf[80];
- X int i;
- X
- X switch(*s) {
- X case '(':
- X if( strchr(s+1, '(')) {
- X syslog(LOG_CRIT,
- X "permissions: [key %s] can't nest brackets\n", s);
- X return;
- X }
- X
- X p = strchr(s, ')');
- X if(p)
- X *p = '\0';
- X else {
- X syslog(LOG_CRIT,
- X "permissions: [key %s] include syntax error\n", s);
- X return;
- X }
- X if( strchr(s, ')')) {
- X syslog(LOG_CRIT,
- X "permissions: [key %s] can't nest brackets\n", s);
- X return;
- X }
- X
- X s++;
- X fin = fopen(s, "r");
- X if(!fin) {
- X syslog(LOG_CRIT,
- X "permissions: [key %s] can't open include\n", s);
- X return;
- X }
- X while( fgets(buf, sizeof buf, fin) ) {
- X for(p=buf; *p; p++)
- X if( *p==' ' || *p=='\n' || *p=='#' || *p=='\t' ) {
- X *p = '\0';
- X break;
- X }
- X if(!*buf)
- X continue;
- X#ifdef DEBUG
- X printf("file: %s '%s'\n", s, buf);
- X#endif
- X grpcheck(buf, add);
- X }
- X fclose(fin);
- X break;
- X case '.':
- X grp = grplist;
- X while(*grp) {
- X if( glob_match(s+1, *grp, 0) )
- X grpusrmatch = add;
- X grp++;
- X }
- X break;
- X default:
- X if( !strcmp(s, usern) )
- X grpusrmatch = add;
- X break;
- X }
- X}
- X
- X%}
- X
- X%token SYMBOL
- X%start permlist
- X
- X%%
- permlist : perm
- X | permlist '|' perm
- X ;
- X
- perm : ttylist ':' grouplist {
- X if(ttymatch!=-1 && grpusrmatch!=-1)
- X allow = ttymatch && grpusrmatch;
- X ttymatch = grpusrmatch = -1;
- X }
- X | '$' SYMBOL { newmap($2); } permlist
- X |
- X ;
- X
- ttylist : tty
- X | ttylist ',' tty
- X ;
- grouplist : group
- X | grouplist ',' group
- X ;
- X
- tty : SYMBOL {
- X if(!ttyn)
- X ttymatch = 1;
- X else if( glob_match($1, ttyn, 0) )
- X ttymatch = 1;
- X }
- X ;
- X
- group : '+' SYMBOL { grpcheck($2, 1); }
- X | '-' SYMBOL { grpcheck($2, 0); }
- X ;
- X%%
- END_OF_FILE
- if test 7791 -ne `wc -c <'perms/perms.y'`; then
- echo shar: \"'perms/perms.y'\" unpacked with wrong size!
- fi
- # end of 'perms/perms.y'
- fi
- if test ! -d 'permtest' ; then
- echo shar: Creating directory \"'permtest'\"
- mkdir 'permtest'
- fi
- if test -f 'permtest/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'permtest/Makefile'\"
- else
- echo shar: Extracting \"'permtest/Makefile'\" \(164 characters\)
- sed "s/^X//" >'permtest/Makefile' <<'END_OF_FILE'
- OBJ = permtest.o ../perms/perms.o ../perms/glob_match.o
- CFLAGS = -g -DPERMS
- X
- permtest: $(OBJ)
- X $(CC) $(LDFLAGS) $(OBJ) -o permtest
- X
- clean:
- X $(RM) *~ *.o permtest
- END_OF_FILE
- if test 164 -ne `wc -c <'permtest/Makefile'`; then
- echo shar: \"'permtest/Makefile'\" unpacked with wrong size!
- fi
- chmod +x 'permtest/Makefile'
- # end of 'permtest/Makefile'
- fi
- if test -f 'permtest/permtest.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'permtest/permtest.c'\"
- else
- echo shar: Extracting \"'permtest/permtest.c'\" \(1614 characters\)
- sed "s/^X//" >'permtest/permtest.c' <<'END_OF_FILE'
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <string.h>
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <netdb.h>
- X#include <grp.h>
- X#include <pwd.h>
- X
- char *grpnames[NGROUPS+1];
- int ngrps;
- struct passwd *pwd;
- struct group *grp;
- int verbose;
- X
- extern int permcheck();
- X
- main(argc, argv)
- char **argv;
- X{
- X char *logn, *ttyn, *hostn;
- X struct hostent *hent;
- X int lp, i;
- X
- X if(argc<4) {
- X fprintf(stderr, "usage: %s [-v] username ttyname hostname\n",
- X *argv);
- X exit(0);
- X }
- X if(!strcmp(argv[1], "-v")) {
- X argv++;
- X verbose=1;
- X }
- X
- X logn = argv[1];
- X ttyn = argv[2];
- X
- X setpwent();
- X pwd = getpwnam(logn);
- X if(!pwd) {
- X fprintf(stderr, "%s: unknown user\n", logn);
- X exit(0);
- X }
- X
- X setgrent();
- X ngrps = 0;
- X if(!(grp=getgrgid(pwd->pw_gid))) {
- X fprintf(stderr,
- X "%d: group id has no name\n", pwd->pw_gid);
- X exit(0);
- X }
- X grpnames[ngrps++] = strdup(grp->gr_name);
- X while( grp=getgrent() ) {
- X if(pwd->pw_gid == grp->gr_gid)
- X continue;
- X while(*grp->gr_mem) {
- X if( !strcmp(logn, *grp->gr_mem)) {
- X grpnames[ngrps++] = strdup(grp->gr_name);
- X }
- X grp->gr_mem++;
- X }
- X }
- X endgrent();
- X grpnames[ngrps] = NULL;
- X
- X if(verbose) {
- X printf("%d group%s:", ngrps, (ngrps>1)?"s":"");
- X for(i=0; i<ngrps; i++)
- X printf(" %s", grpnames[i]);
- X printf("\n");
- X }
- X
- X for( argv= &argv[3]; *argv; argv++) {
- X if((hent = gethostbyname(*argv)))
- X hostn = hent->h_name;
- X else
- X hostn = *argv;
- X lp = permcheck(logn, ttyn, grpnames, hostn);
- X if(verbose)
- X printf("user %s %spermitted on %s:%s\n",
- X logn, lp ? "":"not ", hostn, ttyn);
- X else
- X printf("%s: %s\n", hostn, lp ? "":"not");
- X }
- X exit(0);
- X}
- X
- X
- X
- END_OF_FILE
- if test 1614 -ne `wc -c <'permtest/permtest.c'`; then
- echo shar: \"'permtest/permtest.c'\" unpacked with wrong size!
- fi
- # end of 'permtest/permtest.c'
- fi
- echo shar: End of archive 1 \(of 3\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-